package go;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import utils.OS;

/**
 * @file GO.java
 * @author Juan Humanes Ferrer
 * @date 04-Marzo-2014
 */
public class GO {

    private String org;
    private String bd;
    private TreeGO arbolGO;
    private String raiz;
    private String sesion;

    public GO(String raiz, String sesion, String org) {
        String separator = OS.getDirectorySeparator();
        this.arbolGO = new TreeGO(raiz, sesion, org);
        this.raiz = raiz;
        this.sesion = sesion;
        this.org = org;
        File orgGO = new File(raiz + separator + "orgGO.txt");
        this.bd = archivos.Txt.bdGO(orgGO, org);
    }

    /**
     * Método que retorna el organismo
     *
     * @return org
     */
    public String getOrg() {
        return org;
    }

    /**
     * Método que modifica el organismo
     *
     * @param org
     */
    public void setOrg(String org) {
        this.org = org;
    }

    /**
     * Método que retorna la base de datos en R del organismo
     *
     * @return bd
     */
    public String getBd() {
        return bd;
    }

    /**
     * Método que modifica la base de datos en R del organismo
     *
     * @param bd
     */
    public void setBd(String bd) {
        this.bd = bd;
    }

    /**
     * Método que retorna la ruta de la carpeta temporal
     *
     * @return raiz
     */
    public String getRaiz() {
        return raiz;
    }

    /**
     * Método que modifica la ruta de la carpeta temporal
     *
     * @param raiz
     */
    public void setRaiz(String raiz) {
        this.raiz = raiz;
    }

    /**
     * Método que retorna la sesion del usuario
     *
     * @return sesion
     */
    public String getSesion() {
        return sesion;
    }

    /**
     * Método que modifica la sesion del usuario
     *
     * @param sesion
     */
    public void setSesion(String sesion) {
        this.sesion = sesion;
    }

    /**
     * Método que retorna el arbol de terminos GO
     *
     * @return arbolGO
     */
    public TreeGO getArbolGO() {
        return arbolGO;
    }

    /**
     * Método que modifica el arbol de terminos GO
     *
     * @param arbolGO
     */
    public void setArbolGO(TreeGO arbolGO) {
        this.arbolGO = arbolGO;
    }

    /**
     * Método que crea y ejecuta el script de R que crea un fichero temporal con
     * la lista de terminos e hijos de cada uno
     *
     * @param ont ontologia
     * @throws java.io.IOException
     * @throws java.lang.InterruptedException
     */
    public void ScriptGO_Ontologys(String ont) throws IOException, InterruptedException {
        String separator = OS.getDirectorySeparator();
        String draiz = OS.getR();
        String carpeta = getRaiz() + separator + "go" + separator + getSesion();
        File directorio = new File(carpeta);

        if (directorio.mkdir()) {

        }

        File script = new File(carpeta + separator + "script" + ont + ".R");
        if (script.exists()) {
            script.delete();
            script.createNewFile();
        } else {
            script.createNewFile();
        }

        File salida = new File(carpeta + separator + ont + ".txt");
        if (salida.exists()) {
            salida.delete();
            salida.createNewFile();
        } else {
            salida.createNewFile();
        }
        PrintWriter pwScript;
        String sesionR;
        String barras;
        try (FileWriter scriptW = new FileWriter(carpeta + separator + "script" + ont + ".R")) {
            pwScript = new PrintWriter(scriptW);
            sesionR = "";
            barras = OS.getDoubleDirectorySeparator();
            String[] linea2 = carpeta.split(barras);
            for (int i = 0; i < linea2.length; i++) {
                if (i < linea2.length - 1) {
                    sesionR += linea2[i] + barras;

                } else {
                    sesionR += linea2[i];
                }

            }
            pwScript.flush();
            pwScript.println("library(GO.db)");
            pwScript.flush();
            pwScript.flush();
            pwScript.println("x <- as.list(GO" + ont + "CHILDREN)");
            pwScript.flush();
            pwScript.flush();
            pwScript.println("for (i in 1:length(x)) "
                    + "write(paste(names(x[i]),x[[i]],sep=\" hijo \"),"
                    + "\"" + sesionR + barras + ont + ".txt\",append=TRUE)");
            pwScript.flush();
        }
        pwScript.close();

        Runtime.getRuntime().exec(draiz + sesionR + barras + "script" + ont + ".R");

    }

    /**
     * Método que crea y ejecuta el script de R que crea un fichero temporal con
     * la lista de genes de cada termino
     *
     * @param ontologia
     * @throws java.io.IOException
     * @throws java.lang.InterruptedException
     */
    public void ScriptGO_Genes_Ontology(String ontologia) throws IOException, InterruptedException {
        String separator = OS.getDirectorySeparator();
        String draiz = OS.getR();
        String carpeta = getRaiz() + separator + "go" + separator + getSesion();
        String barras = OS.getDoubleDirectorySeparator();
        File directorio = new File(carpeta);
        if (directorio.mkdir()) {

        }

        File script = new File(carpeta + separator + "scriptG" + ontologia + ".R");
        if (script.exists()) {
            script.delete();
            script.createNewFile();
        } else {
            script.createNewFile();
        }

        File salida = new File(carpeta + separator + "genes" + ontologia + ".txt");
        if (salida.exists()) {
            salida.delete();
            salida.createNewFile();
        } else {
            salida.createNewFile();
        }

        PrintWriter pwScript;
        String sesionR;
        try (FileWriter scriptW = new FileWriter(carpeta + separator + "scriptG" + ontologia + ".R")) {
            pwScript = new PrintWriter(scriptW);
            sesionR = "";
            String[] linea2 = carpeta.split(barras);
            for (int i = 0; i < linea2.length; i++) {
                if (i < linea2.length - 1) {
                    sesionR += linea2[i] + barras;

                } else {
                    sesionR += linea2[i];
                }

            }
            pwScript.flush();
            pwScript.println("library(topGO)");
            pwScript.flush();
            switch (ontologia) {
                case "BP":
                    pwScript.flush();
                    pwScript.println("x <- annFUN.org(\"BP\", mapping = \"org." + bd + ".db\", ID = \"ensembl\")");
                    pwScript.flush();
                    break;
                case "MF":
                    pwScript.flush();
                    pwScript.println("x <- annFUN.org(\"MF\", mapping = \"org." + bd + ".db\", ID = \"ensembl\")");
                    pwScript.flush();
                    break;
                default:
                    pwScript.flush();
                    pwScript.println("x <- annFUN.org(\"CC\", mapping = \"org." + bd + ".db\", ID = \"ensembl\")");
                    pwScript.flush();
                    break;
            }
            pwScript.flush();
            pwScript.println("for (i in 1:length(x)) "
                    + "write(paste(names(x[i]),x[[i]],sep=\" genes \"),"
                    + "\"" + sesionR + barras + "genes" + ontologia + ".txt\",append=TRUE)");
            pwScript.flush();
        }
        pwScript.close();

        Process p = Runtime.getRuntime().exec(draiz + sesionR + barras + "scriptG" + ontologia + ".R");

        p.waitFor();

    }

}
